package com.ydl.hostmonitor.service.impl;

import com.ydl.hostmonitor.service.SystemDetailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class SystemDetailServiceImpl implements SystemDetailService {
    private static final Logger logger = LoggerFactory.getLogger(SystemDetailServiceImpl.class);
    // 写死打包目录（可修改）
    @Value("${log.path:/home}")
    private String DEFAULT_PACKAGE_DIRECTORY;

    @Override
    public Map<String, String> getJvmInfo() {
        Map<String, String> jvmInfo = new HashMap<>();
        jvmInfo.put("版本", System.getProperty("java.version"));
        jvmInfo.put("供应商", System.getProperty("java.vendor"));
        jvmInfo.put("供应商URL", System.getProperty("java.vendor.url"));
        jvmInfo.put("安装路径", System.getProperty("java.home"));
        jvmInfo.put("虚拟机名称", System.getProperty("java.vm.name"));
        jvmInfo.put("虚拟机版本", System.getProperty("java.vm.version"));
        jvmInfo.put("虚拟机供应商", System.getProperty("java.vm.vendor"));
        jvmInfo.put("类版本", System.getProperty("java.class.version"));
        jvmInfo.put("类路径", System.getProperty("java.class.path"));
        jvmInfo.put("内存模型", System.getProperty("java.vm.info"));
        return jvmInfo;
    }

    @Override
    public List<String> getAvailableFonts() {
        List<String> fonts = new ArrayList<>();
        try {
            System.setProperty("java.awt.headless", "true");
            BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = img.createGraphics();
            Font[] allFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
            for (Font font : allFonts) {
                fonts.add(font.getName() + "（" + font.getFamily() + "）");
            }
            g2d.dispose();
        } catch (Exception e) {
            fonts.add("无法获取字体信息: " + e.getMessage());
        }
        return fonts;
    }

    @Override
    public byte[] zipDirectory() throws Exception {
        Path rootPath = Paths.get(DEFAULT_PACKAGE_DIRECTORY).toRealPath(); // 解析真实路径（处理符号链接）

        // 验证目录是否存在
        if (!Files.exists(rootPath) || !Files.isDirectory(rootPath)) {
            throw new IllegalArgumentException("目录不存在或不是有效目录: " + DEFAULT_PACKAGE_DIRECTORY);
        }

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ZipOutputStream zos = new ZipOutputStream(baos)) {

            // 递归添加目录内容（使用NIO的Path）
            addPathToZip(rootPath, rootPath, zos);
            zos.finish();
            return baos.toByteArray();
        }
    }

    // 递归添加文件/目录到ZIP（使用NIO Path处理路径）
    private void addPathToZip(Path rootPath, Path currentPath, ZipOutputStream zos) throws IOException {
        // 计算当前路径相对于根目录的相对路径（核心修复：用NIO的relativize方法）
        Path relativePath = rootPath.relativize(currentPath);
        String entryName = relativePath.toString().replace(File.separator, "/"); // 统一为zip的"/"分隔符

        logger.debug("处理路径: {}，相对路径: {}", currentPath, entryName);

        if (Files.isDirectory(currentPath)) {
            // 目录条目：如果不是根目录，添加目录entry
            if (!relativePath.toString().isEmpty()) {
                zos.putNextEntry(new ZipEntry(entryName + "/")); // 目录必须以/结尾
                zos.closeEntry();
            }
            // 递归处理子目录和文件
            try (Stream<Path> stream = Files.list(currentPath)) {
                stream.forEach(path -> {
                    try {
                        addPathToZip(rootPath, path, zos);
                    } catch (IOException e) {
                        logger.error("处理子路径失败: {}", path, e);
                        throw new RuntimeException("处理文件失败: " + path, e);
                    }
                });
            }
        } else {
            // 文件条目：添加文件内容
            zos.putNextEntry(new ZipEntry(entryName));
            try (InputStream fis = Files.newInputStream(currentPath)) {
                byte[] buffer = new byte[8192];
                int len;
                while ((len = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }
            }
            zos.closeEntry();
        }
    }
}